#pragma once
////////////////////////////////////
/// 编码和解码的基类
#include <mutex>
extern "C" {
#include <libavutil/log.h>
}
struct AVCodecContext;
struct AVFrame;
struct AVPacket;
inline void PrintErr(int err) {
  static char buf[1024];
  memset(buf, 0, sizeof(buf));
  av_strerror(err, buf, sizeof(buf) - 1);
  av_log(nullptr, AV_LOG_ERROR, "%s\n", buf);
}
class XCodec {
public:
  /// @brief 创建编解码器上下文，非线程安全
  /// @param codec_id 编码器id
  /// @return 编码器上下文，失败放回nullptr
  static AVCodecContext *Create(int codec_id, bool is_encode);
  /// @brief 创建编码器上下文，非线程安全
  /// @param name 编码器名称
  /// @return 编码器上下文，失败放回nullptr
  static AVCodecContext *Create(const char *name, bool is_encode);
  /// @brief 设置编码器上下文(也可以用来清理上下文，只需要设置nullptr)，
  /// 线程安全
  /// @param c 编码器上下文
  void set_c(AVCodecContext *c);
  /// 设置编码参数 线程安全
  bool SetOpt(const char *key, const char *val);
  bool SetOpt(const char *key, int val);
  /// 打开编码器 线程安全
  bool Open();
/// 根据AVCodecContext创建一个AVFrame，需要用户管理内存
  AVFrame *CreateFrame();
protected:
  AVCodecContext *c_ = nullptr;
  // 编码器上下文的锁
  std::mutex mux_;
};